home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
By Popular Request 2.0
/
By Popular Request 2.0 (Arsenal Computer).ISO
/
amiga_1
/
amnfrm55.lha
/
Inform
/
examples
/
toyshop.inf
< prev
Wrap
Text File
|
1995-08-02
|
39KB
|
1,012 lines
! ----------------------------------------------------------------------------
! Toyshop: An Inform Demonstration Version 2, 19/8/94
!
! This is not a real game. The main example for Inform 5 is "Advent",
! a port of Colossal Cave. Since that's something of an antique, and most
! of the objects in it are rather simple, this is a collection of more
! exotic features and peculiar objects. Note that "Advent" has plenty of
! interesting doors and also provides a good lantern and bottled water.
!
! To win, simply find 5 interesting things to do and leave by the main exit!
!
! Object An example of...
!
! >SA satchel Container into which the game silently puts things
! >HE helium balloon Something moving under the control of a daemon
! >CA little red car Vehicle, and pushable from place to place
! >PF padded floor Scenery present in several rooms at once
! >GR hand grenade Timed events: a grenade and its pin
! >MA matchbook Simple fire and matches; changing inventory styles
! >WC white candles A stock of objects identical to each other
! >GL white gloves Two independent objects which can behave as a pair
! >CO green cone Easy before and after rules
! >HW high window Starting and stopping daemons
! >BC bolted cupboard A typical locked container (with key)
! >GB glass box Container light can get through
! >SB steel box Container light can't get through
! >CU building cubes A complicated class definition; piles of objects
! >CH Christopher Someone you can talk to, and persuade to do things
! >OF Office Rules about moving in a particular direction
! >TB toothed bag A container with ideas about what it will allow
! >SL spirit level Something to put on top of things
! >BB blackboard A blackboard to write messages on
!
! (The code is marked with >SA and so on for easy access with a text editor)
! ----------------------------------------------------------------------------
Switches dv5;
! First, the banner:
Constant Story "TOYSHOP";
Constant Headline "^An Interactive Demonstration^\
Copyright (c) 1994 by Graham Nelson. All rights given away.^";
! The blackboard code won't compile under Inform 5.2 (because I5.2
! misunderstood '"'); if you're using 5.2, comment out the next line:
Constant WITH_BOARD;
! Now we serve notice to Inform that we do not wish to use the standard
! routine for the Burn action, and will instead be defining our own:
Replace BurnSub;
! And include the first of the three standard library files:
Include "Parser";
! ----------------------------------------------------------------------------
! >SA Ungenerously, the player can only carry at most 4 things, but there's
! a satchel to carry other things around in...
! ----------------------------------------------------------------------------
Object satchel "satchel"
with description "Big and with a smile painted on it.",
name "satchel", article "your",
when_closed "Your satchel lies on the floor.",
when_open "Your satchel lies open on the floor.",
has container open openable;
Constant MAX_OBJECTS 4;
Constant SACK_OBJECT satchel;
! We're going to use the full, most elaborate scoring system the
! library provides, so we define all this...
Constant TASKS_PROVIDED;
Constant NUMBER_TASKS 5;
Global task_scores initial 1 1 1 1 1;
Constant MAX_SCORE 5;
! Finally, include the library of standard verbs and actions...
Include "VerbLib";
! ----------------------------------------------------------------------------
! Off we go into the Toyshop...
! ----------------------------------------------------------------------------
Object Toyshop "Toyshop"
with description
"The centre of a long east-west hall. Shelves are lined \
with toys, painted clowns face you from the walls and \
the floor is lightly padded with colourful mats. A doorway \
leads north, with a red warning triangle above it.",
name "clowns" "painted" "shelves" "triangle",
e_to East_End, w_to West_End, n_to Danger_Zone
has light;
! ----------------------------------------------------------------------------
! >HE The balloon is completely self-contained as a piece of code, except
! that it does not set itself going (though this could have been
! arranged): it is set going in the Initialise() routine.
!
! Notice that the "after" for Drop takes away the "moved" attribute.
! This is a device to ensure that the "initial" message will always be
! the one displayed. (There are other ways of doing this, too.)
! ----------------------------------------------------------------------------
Nearby balloon "helium balloon"
with description "Blue, with a yellow smile.",
name "helium" "balloon" "blue" "string",
initial "A balloon nestles on the ceiling, its long string hanging.",
before
[; Attack: remove self; StopDaemon(self);
"Easily, you burst the balloon. Pop!^^\
Shame it was irreplaceable, really.";
],
after
[; Take: "You take the balloon by its string. It's buoyant!";
Drop: give balloon ~moved;
"The balloon rises gracefully to the ceiling.";
],
time_left 0,
daemon
[ from_room to_room; if (random(3)~=1) rfalse;
from_room=parent(self);
if (from_room==East_End or West_End) to_room=Toyshop;
if (from_room==Toyshop)
{ if (random(2)==1) to_room=East_End;
else to_room=West_End;
}
if (to_room==0) rfalse;
move self to to_room;
if (location==from_room)
print_ret "^A breeze blows the balloon away to the ",
object to_room, ".";
if (location==to_room)
print_ret "^A breeze blows the balloon in from the ",
object from_room, ".";
],
has light; ! Dismal, dismal pun
! ----------------------------------------------------------------------------
! >CA There are two exceptions to the ordinary before/after rules, for
! vehicles and things which can be pushed from place to place: this car
! demonstrates both at once.
!
! The "before" for PushDir (push in a named direction) must call
! AllowPushDir and then return true to signify that the push is legal.
!
! The "before" for Go must return true to signify that travelling in
! the object is legal. (Note that it must also be enterable.)
! ----------------------------------------------------------------------------
Nearby car "little red car"
with name "little" "red" "car" "kar1",
description "Large enough to sit inside. Among the controls is a \
prominent on/off switch. The numberplate is KAR 1.",
when_on "The red car sits here, its engine still running.",
when_off "A little red car is parked here.",
before
[; PushDir: AllowPushDir(); rtrue;
Go: if (car has on) { Achieved(1); "Brmm! Brmm!"; }
print "(The ignition is off at the moment.)^";
],
after
[; PushDir: "The car rolls very slowly as you push it.";
],
has switchable enterable static container open;
Object small_note "small note" car
with name "small" "note",
description
" !!!! FROBOZZ MAGIC CAR COMPANY !!!!^\
^Hello, Driver!^\
^Instructions for use:^\
^Switch on the ignition and off you go!^\
^Warranty:^\
^This car is guaranteed against all defects for a period of \
76 milliseconds from date of purchase or until used, \
whichever comes first.^\
^Good Luck!";
! ----------------------------------------------------------------------------
! >PF An example of an object spread across several (three) rooms:
! ----------------------------------------------------------------------------
Object padded_floor "padded floor"
with name "padded" "floor" "mats" "padding",
description "To protect little children and adventurers.",
before
[; Take: "It is protected from little children and adventurers.";
],
found_in East_End Toyshop West_End
has scenery;
! ----------------------------------------------------------------------------
Object Danger_Zone "Danger Zone"
with description
"This is the Danger Zone, which you should know better \
than to go into. A single door leads back south.",
s_to Toyshop
has light;
! ----------------------------------------------------------------------------
! >GR A classic example of a timer (or, as some people call them and
! appropriately so in this case, a fuse). To demonstrate stopping
! a timer before the alarm (and for fun), there is also a pin:
! ----------------------------------------------------------------------------
Nearby grenade "nasty-looking hand grenade"
with name "hand" "grenade" "nasty" "nasty-looking",
initial "A nasty-looking hand grenade (there is no other kind) \
rolls about irresponsibly on the floor.",
description "Not recommended for children under 90.",
before
[; Pull: if (self has general) "Too late for that.";
StartTimer(self, 5); give self general;
move the_pin to player;
"You pull the pin out, an irrevocable act.";
],
time_left 0,
time_out
[; deadflag=1;
"^An immense explosion suddenly demolishes the toyshop!^^\
Will you never learn?";
],
has transparent;
Object the_pin "pin" grenade
with name "pin",
description "The pin is designed to be easy to pull.",
before
[; Take, Pull: if (self in grenade) <<Pull grenade>>;
Insert:
if (self notin grenade && second==grenade)
{ StopTimer(grenade); move self to grenade;
give grenade ~general;
"Amazing! You got the pin back into the grenade!";
}
];
! ----------------------------------------------------------------------------
! >MA This is a matchbook of five matches, which is quite simple in that you
! can only actually have one match at a time: otherwise, it's quite
! a full implementation. Note that the inventory lines for the match
! and the matchbook are coded here. Note also that the "match" object
! returns to the book even when the book is empty, so that the parser
! will still understand requests for matches - which the "before" rule,
! which automatically removes matches when needed, can then turn down.
!
! The matchbook has a daemon whose job is to tidy up lost matches. One
! might expect this rule to be coded with an "after" routine, to trap
! the player dropping matches. But suppose there were a magpie in the
! game, and it flew down and stole the match but left the matchbook!
! As it happens there isn't, but this is better form.
! ----------------------------------------------------------------------------
Object matchbook "matchbook" Danger_Zone
with name "matchbook" "book" "matches",
number 5,
before
[; Burn: if (match has light)
{ remove match; remove matchbook;
"What a waste of matches!";
}
],
invent
[ i; if (inventory_stage==2)
{ i=self.number;
if (i==0) print " (empty)";
if (i==1) print " (1 match left)";
if (i>1) print " (",i," matches left)";
}
],
description
[ i; print "The cover advertisement reads \
~Curses - Adventure of a Lunchtime~. The book ";
i=self.number;
if (i==0) "is empty.";
if (i==1) "has a single match left.";
print "contains ", i, " matches.^";
],
time_left 0,
daemon
[; if (match notin matchbook && match notin player)
{ move match to matchbook;
if (match has light)
{ give match ~light; StopTimer(match); }
StopDaemon(self);
}
],
has transparent;
Object match "match" matchbook
with parse_name
[ i j; if (self has light) j='burning'; else j='unlit';
while (NextWord()=='match' or j) i++;
return i;
],
time_left 0, article "an",
before
[ i; if (self in matchbook)
{ i=matchbook.number;
if (i==0) "There are no matches left in the book.";
i--; matchbook.number=i;
move self to player; StartDaemon(matchbook);
print "(taking a match from the book, which ";
if (i==0) print "is now empty)^";
if (i==1) print "has one more left)^";
if (i>1) print "has ", i, " left)^";
self.article = "an";
}
Take, Remove: if (self in player) "Done.";
Burn:
if (self has light) "The match is already alight.";
if (matchbook notin player)
"You need the matchbook to strike the match.";
give self light; StartTimer(self, 2+random(3));
self.article = "a";
"You strike the match.";
],
short_name
[; if (self has light) print "burning match";
else print "unlit match";
rtrue;
],
time_out
[; move self to matchbook; give self ~light;
"You drop the match as the flame reaches your finger.";
];
! ----------------------------------------------------------------------------
! >WC And now, a proper solution to the "matchbook problem": a box of candles
! where you really can take as many as you like!
! (Exercise: make the candles lightable. You'll find the game then
! divides candles into lit and unlit ones automatically.)
!
! Actually, there is a more sophisticated way of defining such objects.
! This is almost perfect, except that "take candles" will not pick up
! all the candles in sight (though "take four candles", etc., will work).
! For the deluxe way to code this, see the "Balances" example game.
! ----------------------------------------------------------------------------
Class candle_class
with name "wax" "candle" "candles",
short_name "wax candle", plural "wax candles",
description "It looks just like all the other candles.",
before
[; Burn: "Disappointingly, the wick refuses to burn."; ];
Object candle_box "grey tin box" Danger_Zone
with name "tin" "box" "grey",
description
"A grey tin box of ~Major's Candles~.",
has container openable;
Nearby c1 "c" class candle_class;
Nearby c2 "c" class candle_class;
Nearby c3 "c" class candle_class;
Nearby c4 "c" class candle_class;
Nearby c5 "c" class candle_class;
Nearby c6 "c" class candle_class;
Nearby c7 "c" class candle_class;
Nearby c8 "c" class candle_class;
! ----------------------------------------------------------------------------
Object East_End "East End"
with name "dolls" "nurses",
description
"The eastern end of the toyshop is pink, and dolls and \
nurses line the shelves right up to the high window. \
A dark doorway leads to a northern side chamber.",
w_to Toyshop, n_to DarkRoom
has light;
! ----------------------------------------------------------------------------
! >GL The following example, suggested to the author by Richard Tucker,
! demonstrates an apparently tricky case of objects with associated
! sub-objects. The pair of white gloves behaves just like any other item
! of clothing - but the player can also use the left and right gloves
! independently, can take away or wear only one and so on. When they
! come back together (even in a cupboard, say, or on a mantelpiece)
! they are called a pair again.
!
! We can do this with only three objects, one daemon and one rule.
!
! When the gloves are together, and the player refers to an individual
! glove, the before rule splits up the pair and starts the daemon.
! Once active, the daemon tries every turn to re-join them into a pair.
! (If it succeeds, it turns itself off.)
!
! Note that the "pair of gloves" object has the "general" flag exactly when
! the gloves are apart. When they are together, it contains the individual
! glove objects, and is flagged as "transparent" so that the parser knows
! the player can see and refer to them.
! ----------------------------------------------------------------------------
Nearby gloves "white gloves"
with article "a pair of",
name "white" "gloves" "pair" "of",
time_left 0,
daemon
[; if (parent(right_glove)~=parent(left_glove)) rfalse;
if ((left_glove has worn && right_glove hasnt worn)
|| (left_glove hasnt worn && right_glove has worn)) rfalse;
if (left_glove has worn) give gloves worn; else give gloves ~worn;
move gloves to parent(right_glove); give gloves ~general;
move right_glove to gloves; move left_glove to gloves;
give right_glove ~worn; give left_glove ~worn;
StopDaemon(self);
],
has clothing transparent;
Class glove_class
with article "the",
name "white" "glove",
before
[; if (self notin gloves) rfalse;
move left_glove to parent(gloves); move right_glove to parent(gloves);
if (gloves has worn)
{ give left_glove worn; give right_glove worn;
}
give gloves general; remove gloves;
StartDaemon(gloves);
],
has clothing;
Object left_glove "left glove" gloves
class glove_class
with description "White silk, monogrammed with a scarlet R.",
name "left";
Object right_glove "right glove" gloves
class glove_class,
with description "White silk, monogrammed with a scarlet T.",
name "right";
! ----------------------------------------------------------------------------
! ...and that's all: the "gloves" code is self-contained.
!
! Exercise for the reader: hide a (sharp) jewel inside the left glove.
! (Alter the glove class to make them containers open only when not worn.
! Add two "after" rules to warn the player if there's something sharp
! to the touch, one for putting on the pair of gloves, one for putting on
! an individual glove.)
! ----------------------------------------------------------------------------
! ----------------------------------------------------------------------------
! >CO An example from the manual... but which actually solves a puzzle here:
! ----------------------------------------------------------------------------
Object cone "green cone" East_End
with name "green" "cone" "emerald" "marzipan",
describe
[; if (cone has moved)
"^A misshapen cone of green marzipan sits here.";
"^Nearby is an emerald green cone, one foot high.";
],
description "The cone seems to be made of emerald-coloured \
marzipan.",
before
[; Eat: if (random(100) <= 30)
{ deadflag = 1;
"Unfortunately, you seem to be allergic to almonds.";
}
"You nibble at a corner of the cone.";
],
after
[; Take: "Taken. (Your hands are smeared with marzipan.)";
Drop: cone.description = "The cone is a vague green mess.";
"The cone drops to the floor and sags a little.";
],
has edible;
! ----------------------------------------------------------------------------
! >HW It's the draught from this slightly-concealed window which propels the
! balloon:
! ----------------------------------------------------------------------------
Object high_window "high window" East_End
with name "high" "window",
description
[; print "A narrow, high window ";
if (self has open) "through which a draught blows.";
"which is closed.";
],
after
[; Open: StartDaemon(balloon);
Close: Achieved(2); StopDaemon(balloon);
],
has scenery openable open;
! ----------------------------------------------------------------------------
! >BC A typical locked container, containing a rather pathetic prize...
! ----------------------------------------------------------------------------
Object cupboard "bolted cupboard" East_End
with name "bolted" "cupboard",
describe
[; if (self hasnt open) "^A shut cupboard is bolted to one wall.";
"^Bolted up on one wall is an open cupboard.";
],
with_key key
has locked container openable lockable static;
Object boiled_sweet "boiled sweet" cupboard
with name "boiled" "sweet",
after
[; Eat: Achieved(0);
"It takes an irritatingly long time to eat.";
],
has edible;
! ----------------------------------------------------------------------------
! >GB This is really to demonstrate "transparent". Shutting up the glowing
! >SB ball in the glass box does not make the room go dark: shutting it up
! in the steel box does. Also, you can examine things in the glass box
! even when the glass box is shut.
! ----------------------------------------------------------------------------
Object DarkRoom "Dark Room"
with description "A featureless storage room, hardly worth illumination.",
cant_go "The only exit is back south.",
s_to East_End;
Nearby glass_box "glass box with a lid"
with name "glass" "box" "with" "lid"
has container transparent openable open;
Nearby steel_box "steel box with a lid"
with name "steel" "box" "with" "lid"
has container openable open;
Object West_End "West End"
with name "soldiers" "model" "aircraft" "planes",
description
"The western end of the toyshop is blue, and soldiers and \
model aircraft line the shelves. A small office lies to \
the south.",
e_to Toyshop, s_to Office
has light;
! ----------------------------------------------------------------------------
! >CU An interesting class definition. Imagine trying to code this up
! without classes... (The following is not for the fainthearted.)
!
! Note that with the "describe" routine missing, the game would still
! correctly describe stacks of cubes: just a little less elegantly.
! ----------------------------------------------------------------------------
Attribute is_cube;
Class Cube_Class
with description "Just a child's building block, four inches on a side.",
parse_name
[ i j;
for (::)
{ j=NextWord();
if (j=='block' or 'cube' or 'building' || j==self.name) i++;
else
{ if (j=='blocks' or 'cubes')
{ parser_action=##PluralFound; i++; }
else return i;
}
}
],
describe
[ c d e;
d=child(self);
while (d~=0 && d has is_cube)
{ c++; e=d; d=child(d); }
if (c==0) rfalse;
print "^There is a pile of building blocks here, ";
while (c>=0)
{ print_addr e.name; ! Sneaky: print the "name" out
if (c>0) print " on "; ! using its dictionary address
c--; e=parent(e);
}
".";
],
before
[ c;
PutOn:
if (second has is_cube)
{ if (child(second)~=0 && child(second) has is_cube)
"There's no room on the top of one cube for two more, side \
by side.";
}
else
print "(They're really intended \
to be piled on top of each other.)^";
c=second; while (c has is_cube) c=parent(c);
if (c~=location or mantelpiece) "Too unsteady a base.";
],
after
[ c stack;
PutOn:
stack=noun;
while (parent(stack) has is_cube) { stack=parent(stack); c++; }
if (c<2)
{ if (the_child has general) rtrue;
rfalse;
}
if (c==2) "The pile of three cubes is unsteady, but viable.";
if (the_child has general)
{ Achieved(3);
"^Expertly he keeps the pile of four cubes stable.";
}
stack=noun;
while (parent(stack) has is_cube)
{ c=stack; stack=parent(stack); move c to location; }
"The pile of four cubes wobbles, wobbles, steadies... and suddenly \
collapses!";
Take:
stack=child(noun); if (stack==0) rfalse;
while (stack~=0)
{ c=stack; stack=child(stack); move c to location; }
"Your pile of cubes is collapsed as a result.";
],
has supporter is_cube;
Nearby cube1 "green cube"
class Cube_Class
with name "green";
Nearby cube2 "red cube"
class Cube_Class
with name "red";
Nearby cube3 "yellow cube"
class Cube_Class
with name "yellow";
Nearby cube4 "blue cube"
class Cube_Class
with name "blue";
! ----------------------------------------------------------------------------
! >CH A guest appearance by my cousin Christopher, aged six, who plays with
! one thing at a time (but easily forgets which). Being "transparent"
! (no reflection on him!) means the parser allows the player to examine
! whatever he's playing with... but not to take it from him.
! ----------------------------------------------------------------------------
Nearby the_child "Christopher"
with name "child" "boy" "chris" "christopher",
describe
[; print "^A boy called Christopher sits here";
if (child(the_child)~=0)
{ print ", playing with "; InDefArt(child(the_child));
}
".";
],
life
[ x; Ask:
if (second=='juggling' or 'fluorescent' or 'ball')
"~That's mine!~";
if (second=='helium' or 'balloon')
"Christopher yawns.";
if (second=='cube' or 'cubes')
"~Bet I can make a higher tower than you.~";
if (second=='toys' or 'toyshop')
"~Isn't it fabulous here?~";
"~Dunno.~";
Answer:
if (special_word=='hello' or 'hallo' or 'hi')
"~Hello,~ says Christopher cheerfully.";
"Christopher seems preoccupied.";
Attack: remove self;
"Christopher makes a run for it, effortlessly slipping past you!";
Kiss: "~That's soppy, that is.~";
Give:
if (noun==balloon) "He's too bored by the balloon.";
x=child(the_child);
if (x~=0)
{ move x to location;
print "He forgets about "; DefArt(x); print " and ";
}
else print "He ";
print "eagerly grabs "; DefArt(noun); move noun to the_child; ".";
Order:
if (action==##Drop && noun==child(the_child))
"~Won't! It's mine!~";
if (action==##Take) "Christopher can't be bothered.";
if (action==##Give && second==player)
"~Get your own!~";
if (action==##Go) "~I like it here!~";
if (action==##PutOn)
{ if (noun~=child(the_child)) "He is mightily confused.";
if (noun hasnt is_cube || second hasnt is_cube)
"He can't see the point of this.";
print "Christopher leans over with great concentration \
and does so.^";
move noun to player; give self general;
<PutOn noun second>;
give self ~general; rtrue;
}
],
each_turn
[ i; if (random(3)~=1) rtrue;
print "^Christopher ";
i=random(4); if (i==1) "yawns."; if (i==2) "frowns.";
if (i==3) "stretches."; "hums tonelessly.";
],
has animate proper transparent;
Object ball "fluorescent juggling ball" the_child
with initial "On the floor is a fluorescent juggling ball!",
name "fluorescent" "juggling" "ball",
description "It glows with soft light."
has light;
! ----------------------------------------------------------------------------
! >OF A simple movement rule.
! ----------------------------------------------------------------------------
Object Office "Office"
with description
"A small, grey office, with a broad stone mantelpiece. \
In the east wall is a doorway marked ~Exit~, and the Toyshop, \
of course, lies north.",
cant_go "The Toyshop floor lies north.",
n_to West_End,
e_to
[; if (score~=MAX_SCORE)
print_ret "A gong sounds. ~You cannot leave the Toyshop until \
you have done 5 interesting things!~";
deadflag=2;
"A gong sounds. ~Congratulations! You may now leave the Toyshop \
and begin writing your own Inform game!~";
],
has light;
Nearby mantelpiece "mantelpiece"
with name "mantel" "mantle" "piece" "mantelpiece"
has scenery supporter;
! ----------------------------------------------------------------------------
! >TB A somewhat acquisitive container... but it can be taught to behave.
! ----------------------------------------------------------------------------
Nearby toothed_bag "toothed bag"
with name "toothed" "bag",
initial "In one corner is a curious, toothed bag.",
description "A capacious bag with a toothed mouth.",
before
[; LetGo: "The bag defiantly bites itself \
shut on your hand until you desist.";
],
after
[; Receive:
if (noun==cone)
{ self.before=0; self.after=0;
"The bag wriggles interminably as it tries \
to eat the enormous mass of marzipan. That'll \
teach it.";
}
print "The bag wriggles hideously as it swallows ";
DefArt(inp1); ".";
],
has container open;
! ----------------------------------------------------------------------------
! >SL Which can be put on the mantelpiece: the first time this is done, the
! game randomly decides which end is higher, and sticks to this decision.
! ----------------------------------------------------------------------------
Object spirit_level "spirit level" toothed_bag
with name "spirit" "level" "wood" "flask",
number 0,
description "A length of wood containing a flask of viscous \
green liquid, in which a bubble is trapped.",
before
[; Examine:
if (parent(spirit_level)==mantelpiece)
{ print "The bubble is at the ";
if (self.number==1) "northeast end.";
"southeast end.";
}
],
after
[; PutOn: if (second~=mantelpiece) rfalse;
if (spirit_level hasnt general) self.number=random(2);
give spirit_level general; Achieved(4);
print "You put the spirit level on the mantelpiece, \
and the bubble slowly drifts towards the ";
if (self.number==1) "northeast.";
"southwest.";
];
Object key "iron key" mantelpiece
with name "iron" "key", article "an";
! ----------------------------------------------------------------------------
! >BB A blackboard which can be written on or wiped clear.
! ----------------------------------------------------------------------------
#IFDEF WITH_BOARD;
Object chalk "stick of chalk" mantelpiece
with name "stick" "of" "chalk";
Global boardtext string 64;
Object blackboard "blackboard" Office
with name "board" "blackboard" "black",
describe
[; <<Examine self>>; ],
before
[ i f;
Examine:
for (i=1:i<=boardtext->0:i++)
if (boardtext->i~=' ' or 0) f=1;
if (f==0)
{ print "^The office blackboard is wiped clean.^";
if (self hasnt general)
{ give self general;
"^[To write on it, try > write ~message...~]";
}
rtrue;
}
print "^The office blackboard bears the message:^ ";
for (i=1:i<=boardtext->0:i++)
{ f=boardtext->i;
if (f~=0) print char f;
}
new_line; rtrue;
Rub: for (i=1:i<=boardtext->0:i++) boardtext->i = ' ';
"You wipe the blackboard clean.";
],
has static;
Global from_char; Global to_char;
[ QuotedText i j f;
i = parse->((++wn)*4-3);
if (buffer->i=='"')
{ for (j=i+1:j<=(buffer->1)+1:j++)
if (buffer->j=='"') f=j;
if (f==0) return -1;
from_char = i+1; to_char=f-1;
if (from_char>to_char) return -1;
while (f> (parse->(wn*4-3))) wn++; wn++;
return 1;
}
return -1;
];
[ WriteSub i j;
if (parent(chalk)~=player) "You're holding nothing to write with.";
if (location~=parent(blackboard)) "The blackboard is elsewhere.";
for (i=from_char,j=1:i<=to_char && j<boardtext->0:i++,j++)
boardtext->j = buffer->i;
for (:j<boardtext->0:j++) boardtext->j=0;
<<Examine blackboard>>;
];
#ENDIF;
! ----------------------------------------------------------------------------
! End of object definitions.
! ----------------------------------------------------------------------------
!
! Routines and Entry Points
!
! (Fuller examples can be found in the "Advent" source code.)
!
! Initialise() just sets up the initial state of the game.
! We are required to set "location" to the start location of the
! player; the rest is optional.
!
! StartDaemon(balloon) starts the process which blows the balloon back
! and forth.
! ----------------------------------------------------------------------------
Object chair "chair" Toyshop
with name "chair"
has supporter enterable;
[ Initialise;
location=chair; move satchel to player;
print "^^^^^~What's so special about Inform 5,~ is the last thing you \
remember saying to the mad alchemist. Big mistake...^^";
StartDaemon(balloon);
];
! ----------------------------------------------------------------------------
! Print names of tasks out (when the library asks us to). Note that they
! are numbered from 0 to NUMBER_TASKS-1.
! ----------------------------------------------------------------------------
[ PrintTaskName ach;
if (ach==0) "eating a sweet";
if (ach==1) "driving the car";
if (ach==2) "shutting out the draught";
if (ach==3) "building a tower of four";
if (ach==4) "seeing which way the mantelpiece leans";
];
[ PrintRank;
print ", earning you the rank of ";
if (score >= 5) "Toyshop manager.";
if (score >= 4) "undergraduate.";
if (score >= 3) "schoolchild.";
if (score >= 2) "nursery-school child.";
if (score >= 1) "toddler.";
"newborn baby.";
];
[ HelpMenu;
if (menu_item==0) { item_width=8; item_name="About Adventure";
if (deadflag==2) return 4; else return 3;
}
if (menu_item==1) { item_width=6; item_name="Instructions"; }
if (menu_item==2) { item_width=4; item_name="History"; }
if (menu_item==3) { item_width=6; item_name="Authenticity"; }
if (menu_item==4) { item_width=7; item_name="Did you know..."; }
];
[ GiveHint h k;
print_paddr h; new_line; new_line;
read_char 1 0 0 k;
if (k == 'H' or 'h') rfalse;
rtrue;
];
[ HelpInfo;
if (menu_item==1)
{ print "(Press ENTER to return to the main menu, or H for another hint.)^^";
if (GiveHint("(1/3) The hints may not tell you all at once.")==1) rtrue;
if (GiveHint("(2/3) But keep asking...")==1) rtrue;
"(3/3) ...and the truth is revealed.";
}
if (menu_item==2)
{
DoMenu("There is information provided on the following:^\
^ Balls\
^ Drivel\
^ Goalposts",
#r$HelpMenu, #r$HelpInfo2); return 2;
}
if (menu_item==3)
{
}
];
[ HelpInfo2;
if (menu_item==1) "Different!";
"J. S. Bach.";
];
[ HelpSub;
if (deadflag~=2)
DoMenu("There is information provided on the following:^\
^ Instructions for playing\
^ The history of this game\
^ How authentic is this edition?^",
#r$HelpMenu, #r$HelpInfo);
else
DoMenu("There is information provided on the following:^\
^ Instructions for playing\
^ The history of this game\
^ How authentic is this edition?\
^ Did you know...^",
#r$HelpMenu, #r$HelpInfo);
];
! ----------------------------------------------------------------------------
! Now (as promised earlier) we provide the replacement for BurnSub,
! specially adapted to the rules of the Toyshop:
! ----------------------------------------------------------------------------
[ BurnSub;
if (match hasnt light) "You have no source of flame.";
if (noun has animate) <<Attack noun>>;
if (noun==padded_floor)
{ deadflag=1;
"A gong sounds, but before a sepulchral voice finishes clearing \
its throat, the whole padded floor goes up in an inferno.";
}
"A gong sounds, and a sepulchral, rather disappointed voice says: \
~It is forbidden to play with fire in the Toyshop.~";
];
! ----------------------------------------------------------------------------
! And we provide one new action, "Burst", which in fact just passes over to
! "Attack", plus one for writing on the board:
! ----------------------------------------------------------------------------
[ BurstSub; <<Attack noun>>; ];
Include "Grammar";
Verb "burst" "pop" "prick" "stab" "pierce"
* noun -> Burst;
#IFDEF WITH_BOARD;
Verb "write" * QuotedText -> Write;
#ENDIF;
Verb "help" * -> Help;
! ----------------------------------------------------------------------------